﻿package net.wangit.view.tree;

import net.wangit.support.TreeFactory;
import net.wangit.util.Checker;
import net.wangit.util.ClassUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class TreeProvider {

	private static Log log = LogFactory
			.getLog(net.wangit.view.tree.TreeProvider.class);

	public TreeProvider() {
	}

	public static synchronized Tree getTree(String domain, String treeId) {
		if (Checker.isEmpty(domain) || Checker.isEmpty(treeId)) {
			log.error((new StringBuilder(
					"empty arguments is not acceptable: domain=")).append(
					domain).append(" treeid=").append(treeId).toString());
			return null;
		}
		treeId = treeId.toLowerCase();
		Tree tree = TreeCache.get(domain, treeId);
		if (tree == null) {
			TreeConfig config = TreeConfigFactory.getTreeConfig(domain, treeId);
			tree = createTree(domain, config);
			if (tree == null)
				return null;
			tree.setConfig(config);
			if (config.isCacheEnabled())
				TreeCache.put(domain, treeId, tree);
		}
		return tree;
	}

	private static Tree createTree(String domain, TreeConfig config) {
		String factoryClassName;
		TreeFactory factory;
		factoryClassName = config.getFactory();
		if (Checker.isEmpty(factoryClassName)) {
			factory = new DefaultTreeFactory();
		} else {
			try {
				factory = (TreeFactory) ClassUtil.loadClass(factoryClassName)
						.newInstance();
			} catch (Exception e) {
				log.error((new StringBuilder("could not load TreeFactory: "))
						.append(factoryClassName).append(" for ")
						.append(domain).append("/").append(config.getTreeId())
						.toString());
				throw new TreeConfigurationException((new StringBuilder(
						"could not load TreeFactory: ")).append(
						factoryClassName).toString(), domain, config
						.getTreeId(), "factory", e);
			}
		}
		try {
			factory.setConfig(config);
			return factory.createTree(domain);
		} catch (Exception e) {
			log.error((new StringBuilder("could not create Tree by Factory: "))
					.append(factoryClassName).append(" for ").append(domain)
					.append("/").append(config.getTreeId()).toString());
			throw new TreeConfigurationException((new StringBuilder(
					"could not create Tree by Factory: ")).append(
					factoryClassName).toString(), domain, config.getTreeId(),
					"factory", e);
		}
	}

}
